#include <bits/stdc++.h>

#define eb emplace_back
#define ep emplace
#define fi first
#define se second
#define in read<int>()
#define lin read<ll>()
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using ll = long long;
using db = double;
using pii = pair < int, int >;
using vec = vector < int >;
using veg = vector < pii >;

template < typename T > T read() {
	T x = 0; bool f = 0; char ch = getchar();
	while(!isdigit(ch)) f |= ch == '-', ch = getchar();
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}

template < typename T > void chkmax(T &x, const T &y) { x = x > y ? x : y; }
template < typename T > void chkmin(T &x, const T &y) { x = x < y ? x : y; }

const int N = 1010;
const int M = 20010;

int a[M], b[M], l[M], p[M], L, R;
int n, m;

namespace F { // max_flow
	const int N = 1010;
	const int M = 8e4 + 10;
    const int inf = 0x3f3f3f3f;
    int h[N], now[N], d[N], cnt = 1, S, T;
    struct edge { int v, w, nxt; } e[M << 1];
    inline void tlink(int x, int y, int w) { e[++cnt] = (edge) { y, w, h[x] }; h[x] = cnt; }
    inline void link(int x, int y, int w) { tlink(x, y, w); tlink(y, x, 0); }
    inline void setst(int s, int t) { S = s; T = t; }
	void reset() { cnt = 1; rep(i, 0, n + 1) h[i] = 0; }
    queue < int > q;
    bool bfs() {
		while(q.size()) q.pop(); q.push(S); memset(d, 0, sizeof d); d[S] = 1; now[S] = h[S];
		while(!q.empty()) {
			int x = q.front(); q.pop();
			for(int i = h[x], y; i; i = e[i].nxt)
				if(e[i].w && !d[y = e[i].v]) {
					d[y] = d[x] + 1; q.push(y); now[y] = h[y];
					if(y == T) return 1;
				}
		} return 0;
    }
    int dinic(int x, int flow) {
		if(x == T) return flow;
		int res = flow;
		for(int i = now[x], y; i && res; i = e[i].nxt) {
			now[x] = i;
			if(e[i].w && d[y = e[i].v] == d[x] + 1) {
				int k = dinic(y, min(res, e[i].w));
				if(!k) d[y] = 0; e[i].w -= k; e[i ^ 1].w += k; res -= k;
			}
		}
		return flow - res;
    }
    ll runit() {
		ll maxflow = 0,flow;
		while(bfs()) while(flow = dinic(S, inf)) maxflow += flow;
		return maxflow;
    }
}

int deg[N], eid[M];

bool check(int lim) {
	F :: reset(); rep(i, 1, n) deg[i] = 0;
	rep(i, 1, m) {
		deg[a[i]]++, deg[b[i]]--;
		if(p[i] <= lim) F :: link(a[i], b[i], 1), eid[i] = F :: cnt - 1;
	} F :: setst(0, n + 1); rep(i, 1, n) if(deg[i] & 1) return false; else deg[i] /= 2;
	int tot = 0;
	rep(i, 1, n)
		if(deg[i] > 0) F :: link(0, i, deg[i]), tot += deg[i];
		else if(deg[i] < 0) F :: link(i, F :: T, -deg[i]);
	//cerr << F :: runit() << " " << tot << endl; return true;
	return (F :: runit() == tot);
}

int fa[N];
bool v[N];
int gf(int x) { return fa[x] == x ? x : fa[x] = gf(fa[x]); }

#define GG return puts("NIE"), 0

struct edge { int v, nxt; } e[M << 1];
int h[N], cnt = 0;
int stk[M << 1], top;
bool ban[M << 1];
void link(int x, int y) { e[++cnt] = (edge) { y, h[x] }; h[x] = cnt; }

void dfs(int x) {
	for(int &i = h[x], y = e[i].v; i; i = e[i].nxt, y = e[i].v) {
		if(!ban[i]) {
			ban[i] = true;
			int ti = i; dfs(y); stk[++top] = ti;
		}
	}
}

void work(int res) {
	check(res);
	rep(i, 1, m) {
		if(p[i] <= res) {
			if(F :: e[eid[i]].w) link(a[i], b[i]);
			else link(b[i], a[i]);
		} else link(a[i], b[i]);
	}
	rep(i, 1, n) if(v[i]) { dfs(i); break; }
	while(top) printf("%d ", stk[top--]); puts("");
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("1.in", "r", stdin);
#endif
	n = in, m = in, L = 0, R = 0;
	rep(i, 1, n) fa[i] = i;
	rep(i, 1, m) {
		a[i] = in, b[i] = in, l[i] = in, p[i] = in; fa[gf(a[i])] = gf(b[i]); v[a[i]] = v[b[i]] = true;
		if(l[i] > p[i]) swap(l[i], p[i]), swap(a[i], b[i]);
		chkmax(L, l[i]); chkmax(R, p[i]);
	} int tot = 0, ans = 1001; rep(i, 1, n) { if(!v[i]) tot++; if(gf(i) == i) tot--; }
	if(tot != -1) GG;
	while(L <= R) {
		int mid = L + R >> 1;
		if(check(mid)) ans = mid, R = mid - 1;
		else L = mid + 1;
	} if(ans == 1001) GG; printf("%d\n", ans); work(ans);
	return 0;
}
